package com.air.config;

import com.air.json.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.List;

/**
 * 配置类，继承自WebMvcConfigurationSupport，用于配置Spring MVC的细节。
 * 同时利用Lombok的@Slf4j注解，引入日志门面。
 */
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    /**
     * 配置Swagger文档，用于生成旅客端接口的API文档。
     * 使用Docket Bean来配置Swagger的属性，如API信息、分组名称和包路径等。
     *
     * @return 返回配置后的Docket对象。
     */
    @Bean
    public Docket docket1() {
        log.info("准备生成接口文档...");
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("智慧机场项目接口文档")
                .version("2.0")
                .description("智慧机场项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("旅客端接口")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.air.controller.passenger"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

    /**
     * 配置Swagger文档，用于生成航空端接口的API文档。
     * 方法与docket1类似，主要区别在于配置的包路径和分组名称。
     *
     * @return 返回配置后的Docket对象。
     */
    @Bean
    public Docket docket2() {
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("智慧机场项目接口文档")
                .version("2.0")
                .description("智慧机场项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("航空端接口")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.air.controller.airline"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

    /**
     * 配置静态资源的映射路径。
     * 使得应用能够处理静态资源请求，如doc.html和webjars下的资源。
     *
     * @param registry 用于注册静态资源处理的Registry对象。
     */
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    /**
     * 扩展Spring MVC的消息转换器。
     * 通过添加自定义的MappingJackson2HttpMessageConverter，配置应用使用JacksonObjectMapper进行JSON的序列化和反序列化。
     *
     * @param converters Spring MVC的消息转换器列表。
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 创建一个MappingJackson2HttpMessageConverter对象，并配置其使用自定义的JacksonObjectMapper
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(new JacksonObjectMapper());
        // 将自定义的消息转换器添加到列表的最前面
        converters.add(0, converter);
    }
}
